-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Statically track the status of a Response by using a Phantom Type #19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
aa3f57d to
1aab0fd
Compare
src/server/response.rs
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left over *Response from a previous attempt?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup. Will rebase.
|
I really quite like this idea. I want the compiler to catch when you try to set a header after writing. Dynamic is slower, and has errors show up in actual programs instead. If I merge this and #17, then Response's will be generic over 2 things, right? Does this feel painful as a framework dev? |
Introduces two Phantom Types, Fresh and Streaming, which indicate the status of a Response. Response::start translates an Response<Fresh> into a Response<Streaming> by writing the StatusCode and Headers. Response<Fresh> allows modification of Headers and StatusCode, but does not allow writing to the body. Response<Streaming> has the opposite privileges.
1aab0fd to
13bb07e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've never been a fan of assignment via derefing a pointer... What if it were fn set_status(StatusCode)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm. I think people in Rust are used to assign-via-deref because this is a relatively common pattern, but I'm not opposed to set_status in principle. I wonder if there is a style guide convention for this case.
|
We should investigate if making #17 use dynamic dispatch creates a material difference in performance, if so, then yes, that sounds a tiny bit annoying. However, I think it's useful enough to justify it. Most frameworks will probably not expose Request and Response directly, so I don't think it's too big of an issue. It's mostly useful for testing so one can mock Incoming, though it would probably be easier to just make http requests with a good client. |
Statically track the status of a Response by using a Phantom Type
Introduces two Phantom Types, Fresh and Streaming, which indicate the status
of a Response.
Response::start translates an Response into a Response by
writing the StatusCode and Headers.
Response allows modification of Headers and StatusCode, but does
not allow writing to the body. Response has the opposite privileges.
Disadvantages:
Uses a Phantom Type, which some may find confusing.
Alternatives:
Continue to track this dynamically and provide publicly accessible methods for
conditionally updating Headers and StatusCode and disallow direct access or
mutation.
Keep doing what we do now, but expose headers_written.
Split Response into two structs and create a Response trait. This introduces
code duplication and new ways to interact with Headers and Status.
Fixes #6